x86/fpu: add mask parameter to xsave and xrstor
authorWei Huang <wei.huang2@amd.com>
Mon, 9 May 2011 10:38:55 +0000 (11:38 +0100)
committerWei Huang <wei.huang2@amd.com>
Mon, 9 May 2011 10:38:55 +0000 (11:38 +0100)
Xen currently sets mask bits of xsave() and xrstor() to all 1's. This
patch adds a mask option to xsave() and xrstor().

Signed-off-by: Wei Huang <wei.huang2@amd.com>
xen/arch/x86/i387.c
xen/arch/x86/xstate.c
xen/include/asm-x86/xstate.h

index fc0c1c45f4f27e4ea12295a8c170ef3fb513c5d4..9350f734d519d37d3f485bbf26f75aa0abc419db 100644 (file)
@@ -35,14 +35,14 @@ static void fpu_init(void)
 /*     FPU Restore Functions   */
 /*******************************/
 /* Restore x87 extended state */
-static inline void fpu_xrstor(struct vcpu *v)
+static inline void fpu_xrstor(struct vcpu *v, uint64_t mask)
 {
     /*
      * XCR0 normally represents what guest OS set. In case of Xen itself, 
      * we set all supported feature mask before doing save/restore.
      */
     set_xcr0(v->arch.xcr0_accum);
-    xrstor(v);
+    xrstor(v, mask);
     set_xcr0(v->arch.xcr0);
 }
 
@@ -98,13 +98,13 @@ static inline void fpu_frstor(struct vcpu *v)
 /*      FPU Save Functions     */
 /*******************************/
 /* Save x87 extended state */
-static inline void fpu_xsave(struct vcpu *v)
+static inline void fpu_xsave(struct vcpu *v, uint64_t mask)
 {
     /* XCR0 normally represents what guest OS set. In case of Xen itself,
      * we set all accumulated feature mask before doing save/restore.
      */
     set_xcr0(v->arch.xcr0_accum);
-    xsave(v);
+    xsave(v, mask);
     set_xcr0(v->arch.xcr0);    
 }
 
@@ -174,7 +174,7 @@ void vcpu_restore_fpu(struct vcpu *v)
         return;
 
     if ( xsave_enabled(v) )
-        fpu_xrstor(v);
+        fpu_xrstor(v, XSTATE_ALL);
     else if ( v->fpu_initialised )
     {
         if ( cpu_has_fxsr )
@@ -204,7 +204,7 @@ void vcpu_save_fpu(struct vcpu *v)
     clts();
 
     if ( xsave_enabled(v) )
-        fpu_xsave(v);
+        fpu_xsave(v, XSTATE_ALL);
     else if ( cpu_has_fxsr )
         fpu_fxsave(v);
     else
index e358fd7bbd803aff3fe12aef5ec810bbf91e61ba..fdb80d37ab19322479a9ce0550b81986738dd786 100644 (file)
@@ -51,32 +51,37 @@ inline uint64_t get_xcr0(void)
     return this_cpu(xcr0);
 }
 
-void xsave(struct vcpu *v)
+void xsave(struct vcpu *v, uint64_t mask)
 {
     struct xsave_struct *ptr = v->arch.xsave_area;
+    uint32_t hmask = mask >> 32;
+    uint32_t lmask = mask;
 
     if ( cpu_has_xsaveopt )
         asm volatile (
             ".byte " REX_PREFIX "0x0f,0xae,0x37"
             :
-            : "a" (-1), "d" (-1), "D"(ptr)
+            : "a" (lmask), "d" (hmask), "D"(ptr)
             : "memory" );
     else
         asm volatile (
             ".byte " REX_PREFIX "0x0f,0xae,0x27"
             :
-            : "a" (-1), "d" (-1), "D"(ptr)
+            : "a" (lmask), "d" (hmask), "D"(ptr)
             : "memory" );
 }
 
-void xrstor(struct vcpu *v)
+void xrstor(struct vcpu *v, uint64_t mask)
 {
+    uint32_t hmask = mask >> 32;
+    uint32_t lmask = mask;
+
     struct xsave_struct *ptr = v->arch.xsave_area;
 
     asm volatile (
         ".byte " REX_PREFIX "0x0f,0xae,0x2f"
         :
-        : "m" (*ptr), "a" (-1), "d" (-1), "D"(ptr) );
+        : "m" (*ptr), "a" (lmask), "d" (hmask), "D"(ptr) );
 }
 
 bool_t xsave_enabled(const struct vcpu *v)
index a0677173fd34beb0d07d5de354df02b41a8a6b53..2ff495b22614e0b7ef57e4fbe8bfa61262f3cb67 100644 (file)
 #define XSTATE_FP_SSE  (XSTATE_FP | XSTATE_SSE)
 #define XCNTXT_MASK    (XSTATE_FP | XSTATE_SSE | XSTATE_YMM | XSTATE_LWP)
 
+#define XSTATE_ALL     (~0)
+#define XSTATE_NONLAZY (XSTATE_LWP)
+#define XSTATE_LAZY    (XSTATE_ALL & ~XSTATE_NONLAZY)
+
 #ifdef CONFIG_X86_64
 #define REX_PREFIX     "0x48, "
 #else
@@ -56,8 +60,8 @@ struct xsave_struct
 /* extended state operations */
 void set_xcr0(u64 xfeatures);
 uint64_t get_xcr0(void);
-void xsave(struct vcpu *v);
-void xrstor(struct vcpu *v);
+void xsave(struct vcpu *v, uint64_t mask);
+void xrstor(struct vcpu *v, uint64_t mask);
 bool_t xsave_enabled(const struct vcpu *v);
 
 /* extended state init and cleanup functions */